/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package busquedaEstrella;

/**
 *
 * Clase que modela un estado del tablero para la busqueda estrella
 */
public class NodoE {
    public int idPadre; //id al padre del nodo
    public int id; //id al nodo en cuestion
    public int[][] Posicion; //estado del tablero
    public int[][] Peso; //pesos para el tablero
    public int f; //valor de la funcion heuristica f' para el nodo correspondiente
    public int g; //valor de g
    public boolean cerrado; // indica si el nodo esta marcado como cerrado si es true
    public int nivel; //nivel en el que se encuentra el nodo
    public NodoE (int [][] matrizInicial, int idPadre, int id, int nivel, int g){
        // Aca cargamos los valores de la matriz de posiciones actual
        this.idPadre = idPadre;
        this.id = id;
        this.g = g;
        this.f = 0;
        this.cerrado = false;
        this.nivel = nivel;
        Posicion = new int [8][8];
        Peso = new int[8][8];
        for (int i=0; i<8; i++){
            for (int j=0; j<8; j++){
                Posicion[i][j] = matrizInicial [i][j];
            }
        }

        // ahora cargamos la matriz de peso actual
        int cuadranteCN;
        cuadranteCN = this.cuadranteCN();

        int pesoCuadrante1 = 0;
        int pesoCuadrante2 = 0;
        int pesoCuadrante3 = 0;
        int pesoCuadrante4 = 0;

        switch(cuadranteCN){
            case 1: pesoCuadrante1 = 5; pesoCuadrante2 = 10; pesoCuadrante3 = 10; pesoCuadrante4 = 15; break;
            case 2: pesoCuadrante1 = 10; pesoCuadrante2 = 5; pesoCuadrante3 = 15; pesoCuadrante4 = 10; break;
            case 3: pesoCuadrante1 = 10; pesoCuadrante2 = 15; pesoCuadrante3 = 5; pesoCuadrante4 = 10; break;
            case 4: pesoCuadrante1 = 15; pesoCuadrante2 = 10; pesoCuadrante3 = 10; pesoCuadrante4 = 5; break;

        }
        //cargamos cada cuadrante individual
        for(int a=0; a<8;a++){
            for(int b=0;b<8;b++){
                if((a<4)&&(b<4)){                    
                       this.Peso[a][b] = pesoCuadrante1;                   
                }
                if((a<4)&&(b>3)){
                       this.Peso[a][b] = pesoCuadrante2;                   
                }
                if((a>3)&&(b<4)){                   
                       this.Peso[a][b] = pesoCuadrante3;                    
                }
                if((a>3)&&(b>3)){                    
                       this.Peso[a][b] = pesoCuadrante4;                  
                }
                //
                if(this.Posicion[a][b]==0){

                    this.Peso[a][b] =0;
                }
                //
                if(this.Posicion[a][b]==2){

                    this.Peso[a][b] =0;
                }

            }
        }
        this.f = 0;
    }

    //Metodos para hacer modificaciones al nodo
    public void modificarPosicion (int i, int j, int valor){
        // Este metodo modifica el valor de la posicion en la que se encuentra.
        getPosicion()[i][j] = valor;
    }
    //Metodod para modficiar una posicion de la matriz de pesos
    public void modificarPeso (int i, int j, int peso){
        // Este metodo modifica el valor del peso en la posicion en la que se encuentra.
        getPeso()[i][j] = peso;
    }

    //metodo que determina la fila del caballo negro
    public int filaCN(){
        int fila = 0;
        for(int i=0;i<8;i++){
            for(int j=0;j<8;j++){

                if(this.getPosicion()[i][j]==2){
                    fila = i;
                }

            }
        }

        return fila;

    }
    //metodo que devuelve la columna del caballo negro
    public int colCN(){
        int col = 0;
        for(int i=0;i<8;i++){
            for(int j=0;j<8;j++){

                if(this.getPosicion()[i][j]==2){
                    col = j;
                }

            }
        }
        return col;

    }

    /**
     * @return the Posicion
     */
    public int[][] getPosicion() {
        return Posicion;
    }

    /**
     * @param Posicion the Posicion to set
     */
    public void setPosicion(int[][] Posicion) {
        this.Posicion = Posicion;
    }

    /**
     * @return the Peso
     */
    public int[][] getPeso() {
        return Peso;
    }

    /**
     * @param Peso the Peso to set
     */
    public void setPeso(int[][] Peso) {
        this.Peso = Peso;
    }

    /**
     * @return the costo
     */
    //Muestra en consola los valores del nodo
    public void mostrarValores(){
        System.out.println("Mostrar matriz de posiciones");
        for(int i=0;i<8;i++){
            for(int j=0;j<8;j++){
                System.out.print(this.Posicion[i][j]);
            }
            System.out.println();
        }

        System.out.println("Mostrar matriz de pesos");
        for(int p=0;p<8;p++){
            for(int m=0;m<8;m++){
                System.out.print(this.Peso[p][m]);
            }
            System.out.println();
        }

        System.out.println();
        System.out.println("Id Nodo Padre: "+this.getIdPadre());
        System.out.println("Id Nodo: "+this.getId());
        System.out.println("Nivel: "+this.getNivel());
        System.out.println("Valor Función Heurística: "+this.f);

   }

    
    /**
     * @return the idPadre
     */
    public int getIdPadre() {
        return idPadre;
    }

    /**
     * @param idPadre the idPadre to set
     */
    public void setIdPadre(int idPadre) {
        this.idPadre = idPadre;
    }

    /**
     * @return the id
     */
    public int getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * @return the f
     */
    public int getF() {
        return f;
    }

    /**
     * @param f the f to set
     */
    public void setF(int f) {
        this.f = f;
    }

    //Metodos auxiliares
    public int cuadranteCN(){
        //cuadrante superior izquierdo
        int cuadrante = 1;
        int filaCN = this.filaCN();
        int colCN= this.colCN();
        if((filaCN<=4)&&(colCN<=4)){

        }
        //cuadrante superior derecho
        if((filaCN<=4)&&(colCN>=5)){
            cuadrante = 2;
        }
        // cuadrante inferior izquierdo
        if((filaCN>=5)&&(colCN<=4)){
            cuadrante = 3;
        }
        // cuadrante inferior derecho
        if((filaCN>=5)&&(colCN>=5)){
            cuadrante = 4;
        }
        return cuadrante;

    }
    //Metodo para calcular la funcion heuristica
    public void calcularF(){

        this.f = this.getG() + this.calcularH();
        
    }
    //Metodo para calcular el valor de h'
    private int calcularH(){
        /* h' = 5 * X + 10 * Y + 15 * Z
         *
         * Donde:
         *  X = cantidad de caballos blancos en el cuadrante donde esta el caballo negro
         *  Y = cantidad de caballos blancos en los cuadrantes adyacentes
         *  Z = cantidad de caballos blancos en el cuadrante restante
         *
         */
        int h = 0;
        for(int i=0;i<8;i++){
            for(int j=0;j<8;j++){
                h = h + this.Peso[i][j];
            }
        }
        return h;
    }

    public int getG() {
        return g;
    }

    /**
     * @param g the g to set
     */
    public void setG(int g) {
        this.g = g;
    }

    //Metodo auxiliar
    public void actualizarPesos(){
        int cuadranteCN;
        cuadranteCN = this.cuadranteCN();
        int pesoCuadrante1 = 0;
        int pesoCuadrante2 = 0;
        int pesoCuadrante3 = 0;
        int pesoCuadrante4 = 0;
        switch(cuadranteCN){
            case 1: pesoCuadrante1 = 5; pesoCuadrante2 = 10; pesoCuadrante3 = 10; pesoCuadrante4 = 15; break;
            case 2: pesoCuadrante1 = 10; pesoCuadrante2 = 5; pesoCuadrante3 = 15; pesoCuadrante4 = 10; break;
            case 3: pesoCuadrante1 = 10; pesoCuadrante2 = 15; pesoCuadrante3 = 5; pesoCuadrante4 = 10; break;
            case 4: pesoCuadrante1 = 15; pesoCuadrante2 = 10; pesoCuadrante3 = 10; pesoCuadrante4 = 5; break;

        }
        //cargamos cada cuadrante individual
        for(int a=0; a<8;a++){
            for(int b=0;b<8;b++){

                if((a<4)&&(b<4)){

                       this.Peso[a][b] = pesoCuadrante1;
                }

                if((a<4)&&(b>3)){
                       this.Peso[a][b] = pesoCuadrante2;

                }

                if((a>3)&&(b<4)){


                       this.Peso[a][b] = pesoCuadrante3;

                }

                if((a>3)&&(b>3)){
                       this.Peso[a][b] = pesoCuadrante4;

                }
                //
                if(this.Posicion[a][b]==0){

                    this.Peso[a][b] =0;
                }
                //
                if(this.Posicion[a][b]==2){

                    this.Peso[a][b] =0;
                }

            }
        }
    }

    /**
     * @return the cerrado
     */
    public boolean isCerrado() {
        return cerrado;
    }

    /**
     * @param cerrado the cerrado to set
     */
    public void setCerrado(boolean cerrado) {
        this.cerrado = cerrado;
    }

    /**
     * @return the nivel
     */
    public int getNivel() {
        return nivel;
    }

    /**
     * @param nivel the nivel to set
     */
    public void setNivel(int nivel) {
        this.nivel = nivel;
    }
}
